Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


Bluetooth.h HEAD (a42f8d32) Text, 19.44 KB

T8b949e// Copyright (C) 2024, Mark Qvist

T8b949e// This program is free software: you can redistribute it and/or modify
T8b949e// it under the terms of the GNU General Public License as published by
T8b949e// the Free Software Foundation, either version 3 of the License, or
T8b949e// (at your option) any later version.

T8b949e// This program is distributed in the hope that it will be useful,
T8b949e// but WITHOUT ANY WARRANTY; without even the implied warranty of
T8b949e// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
T8b949e// GNU General Public License for more details.

T8b949e// You should have received a copy of the GNU General Public License
T8b949e// along with this program. If not, see <https://www.gnu.org/licenses/>.

Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Tff7b72#Tff7b72if HAS_BLUETOOTH == true
Tff7b72#Tff7b72include T8b949e"BluetoothSerial.h"
Tff7b72#Tff7b72include T8b949e"esp_bt_main.h"
Tff7b72#Tff7b72include T8b949e"esp_bt_device.h"
Te6edf3BluetoothSerial Te6edf3SerialBTTb4b4b4;
Tff7b72#Tff7b72elif HAS_BLE == true
Tff7b72#Tff7b72include T8b949e"esp_bt_main.h"
Tff7b72#Tff7b72include T8b949e"esp_bt_device.h"
Tff7b72#Tff7b72include T8b949e"src/ble/BLESerial.h"
Te6edf3BLESerial Te6edf3SerialBTTb4b4b4;
Tff7b72#Tff7b72endif

Tff7b72#Tff7b72elif MCU_VARIANT == MCU_NRF52
Tff7b72#Tff7b72include T8b949e<bluefruit.h>
Tff7b72#Tff7b72include T8b949e<math.h>
Tff7b72#Tff7b72define BLE_RX_BUF 6144
Te6edf3BLEUart Td2a8ffSerialBTTb4b4b4(Te6edf3BLE_RX_BUFTb4b4b4)Tb4b4b4;
Te6edf3BLEDis Te6edf3bledisTb4b4b4;
Te6edf3BLEBas Te6edf3blebasTb4b4b4;
Tffa657bool Te6edf3SerialBT_init Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72endif

Tff7b72#Tff7b72define BT_PAIRING_TIMEOUT 35000
Tff7b72#Tff7b72define BLE_FLUSH_TIMEOUT 20
Tffa657uint32_t Te6edf3bt_pairing_started Tff7b72= T79c0ff0Tb4b4b4;

Tff7b72#Tff7b72define BT_DEV_ADDR_LEN 6
Tff7b72#Tff7b72define BT_DEV_HASH_LEN 16
Tffa657uint8_t Te6edf3dev_bt_macTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4]Tb4b4b4;
Tffa657char Te6edf3bt_daTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4]Tb4b4b4;
Tffa657char Te6edf3bt_dhTb4b4b4[Te6edf3BT_DEV_HASH_LENTb4b4b4]Tb4b4b4;
Tffa657char Te6edf3bt_devnameTb4b4b4[T79c0ff11Tb4b4b4]Tb4b4b4;

Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Tff7b72#Tff7b72if HAS_BLUETOOTH == true

Tffa657void Td2a8ffbt_confirm_pairingTb4b4b4(Tffa657uint32_t Te6edf3numValTb4b4b4) Tb4b4b4{
Te6edf3bt_ssp_pin Tff7b72= Te6edf3numValTb4b4b4;
Te6edf3kiss_indicate_btpinTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairingTb4b4b4) Tb4b4b4{
Te6edf3SerialBTTb4b4b4.Te6edf3confirmReplyTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialBTTb4b4b4.Te6edf3confirmReplyTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_stopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72!Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3SerialBTTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_startTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3SerialBTTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3bt_devnameTb4b4b4)Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_enable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_allow_pairing Tff7b72= Tffa657trueTb4b4b4;
Te6edf3bt_pairing_started Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_PAIRINGTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_disable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_pairing_completeTb4b4b4(Te6edf3boolean Te6edf3successTb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3successTb4b4b4) Tb4b4b4{
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3bt_ssp_pin Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_connection_callbackTb4b4b4(Te6edf3esp_spp_cb_event_t Te6edf3eventTb4b4b4, Te6edf3esp_spp_cb_param_t Tff7b72*Te6edf3paramTb4b4b4) Tb4b4b4{
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Te6edf3event Tff7b72=Tff7b72= Te6edf3ESP_SPP_SRV_OPEN_EVTTb4b4b4) Tb4b4b4{
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4;
Te6edf3cable_state Tff7b72= Te6edf3CABLE_STATE_DISCONNECTEDTb4b4b4;
Tb4b4b4}
Tff7b72ifTb4b4b4(Te6edf3event Tff7b72=Tff7b72= Te6edf3ESP_SPP_CLOSE_EVT Tb4b4b4)Tb4b4b4{
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Td2a8ffbt_setup_hwTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3bt_readyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_CONF_BTTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3BT_ENABLE_BYTETb4b4b4) Tb4b4b4{
Te6edf3bt_enabled Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3bt_enabled Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3btStartTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3esp_bluedroid_initTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ESP_OKTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3esp_bluedroid_enableTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ESP_OKTb4b4b4) Tb4b4b4{
Tff7b72const Tffa657uint8_tTff7b72* Te6edf3bda_ptr Tff7b72= Te6edf3esp_bt_dev_get_addressTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657char Tff7b72*Te6edf3data Tff7b72= Tb4b4b4(Tffa657charTff7b72*Tb4b4b4)Te6edf3mallocTb4b4b4(Te6edf3BT_DEV_ADDR_LENTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3BT_DEV_ADDR_LENTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3bda_ptrTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tb4b4b4}
Te6edf3dataTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4] Tff7b72= Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_SIGNATURETb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657unsigned Tffa657char Tff7b72*Te6edf3hash Tff7b72= Te6edf3MD5Tff7b72:Tff7b72:Te6edf3make_hashTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3BT_DEV_ADDR_LENTb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3bt_dhTb4b4b4, Te6edf3hashTb4b4b4, Te6edf3BT_DEV_HASH_LENTb4b4b4)Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3bt_devnameTb4b4b4, Ta5d6ff"Ta5d6ffRNode %02X%02XTa5d6ff"Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff14Tb4b4b4]Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff15Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3freeTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4;

Te6edf3SerialBTTb4b4b4.Te6edf3enableSSPTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3onConfirmRequestTb4b4b4(Te6edf3bt_confirm_pairingTb4b4b4)Tb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3onAuthCompleteTb4b4b4(Te6edf3bt_pairing_completeTb4b4b4)Tb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3register_callbackTb4b4b4(Te6edf3bt_connection_callbackTb4b4b4)Tb4b4b4;
Te6edf3bt_ready Tff7b72= Tffa657trueTb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;

Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4}

Tffa657bool Td2a8ffbt_initTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_setup_hwTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_enabled Tff7b72&Tff7b72& Tff7b72!Te6edf3console_activeTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffupdate_btTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairing Tff7b72&Tff7b72& Te6edf3millisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3bt_pairing_started Tff7b72>Tff7b72= Te6edf3BT_PAIRING_TIMEOUTTb4b4b4) Tb4b4b4{
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tff7b72#Tff7b72elif HAS_BLE == true
Tffa657bool Td2a8ffbt_setup_hwTb4b4b4(Tb4b4b4)Tb4b4b4; Tffa657void Td2a8ffbt_security_setupTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3BLESecurity Tff7b72*Te6edf3ble_security Tff7b72= Te6edf3new Te6edf3BLESecurityTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3ble_authenticated Tff7b72= Tffa657falseTb4b4b4;
Tffa657uint32_t Te6edf3pairing_pin Tff7b72= T79c0ff0Tb4b4b4;

Tffa657void Td2a8ffbt_flushTb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4) Tb4b4b4{ Te6edf3SerialBTTb4b4b4.Te6edf3flushTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4} Tb4b4b4}

Tffa657void Td2a8ffbt_startTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT start");
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3bt_devnameTb4b4b4)Tb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3setTimeoutTb4b4b4(T79c0ff10Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_stopTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT stop");
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72!Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Te6edf3SerialBTTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Td2a8ffbt_initTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT init");
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_setup_hwTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_enabled Tff7b72&Tff7b72& Tff7b72!Te6edf3console_activeTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_debond_allTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Debonding all");
Tffa657int Te6edf3dev_num Tff7b72= Te6edf3esp_ble_get_bond_device_numTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_bond_dev_t Tff7b72*Te6edf3dev_list Tff7b72= Tb4b4b4(Te6edf3esp_ble_bond_dev_t Tff7b72*Tb4b4b4)Te6edf3mallocTb4b4b4(Tff7b72sizeofTb4b4b4(Te6edf3esp_ble_bond_dev_tTb4b4b4) Tff7b72* Te6edf3dev_numTb4b4b4)Tb4b4b4;
Te6edf3esp_ble_get_bond_device_listTb4b4b4(Tff7b72&Te6edf3dev_numTb4b4b4, Te6edf3dev_listTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3dev_numTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{ Te6edf3esp_ble_remove_bond_deviceTb4b4b4(Te6edf3dev_listTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3bd_addrTb4b4b4)Tb4b4b4; Tb4b4b4}
Te6edf3freeTb4b4b4(Te6edf3dev_listTb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_enable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT enable pairing");
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3bt_security_setupTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3bt_allow_pairing Tff7b72= Tffa657trueTb4b4b4;
Te6edf3bt_pairing_started Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_PAIRINGTb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= Te6edf3pairing_pinTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_disable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT disable pairing");
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_passkey_notify_callbackTb4b4b4(Tffa657uint32_t Te6edf3passkeyTb4b4b4) Tb4b4b4{
T8b949e// Serial.printf("Got passkey notification: %d\n", passkey);
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairingTb4b4b4) Tb4b4b4{
Te6edf3bt_ssp_pin Tff7b72= Te6edf3passkeyTb4b4b4;
Te6edf3bt_pairing_started Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_btpinTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Serial.println("Pairing not allowed, re-init");
Te6edf3SerialBTTb4b4b4.Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Td2a8ffbt_confirm_pin_callbackTb4b4b4(Tffa657uint32_t Te6edf3pinTb4b4b4) Tb4b4b4{
T8b949e// Serial.printf("Confirm PIN callback: %d\n", pin);
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_update_passkeyTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Updating passkey");
Te6edf3pairing_pin Tff7b72= Te6edf3randomTb4b4b4(T79c0ff899999Tb4b4b4)Tff7b72+T79c0ff100000Tb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= Te6edf3pairing_pinTb4b4b4;
Tb4b4b4}

Tffa657uint32_t Td2a8ffbt_passkey_callbackTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("API passkey request");
Tff7b72if Tb4b4b4(Te6edf3pairing_pin Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ Te6edf3bt_update_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}
Tff7b72return Te6edf3pairing_pinTb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffbt_client_authenticatedTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3ble_authenticatedTb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffbt_security_request_callbackTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairingTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Accepting security request");
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Serial.println("Rejecting security request");
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_authentication_complete_callbackTb4b4b4(Te6edf3esp_ble_auth_cmpl_t Te6edf3auth_resultTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3auth_resultTb4b4b4.Te6edf3success Tff7b72=Tff7b72= Tffa657trueTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Authentication success");
Te6edf3ble_authenticated Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_PAIRINGTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Pairing complete, disconnecting");
Te6edf3delayTb4b4b4(T79c0ff2000Tb4b4b4)Tb4b4b4; Te6edf3SerialBTTb4b4b4.Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Serial.println("Authentication fail");
Te6edf3ble_authenticated Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Te6edf3bt_update_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_security_setupTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_connect_callbackTb4b4b4(Te6edf3BLEServer Tff7b72*Te6edf3serverTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3conn_id Tff7b72= Te6edf3serverTff7b72-Tff7b72>Te6edf3getConnIdTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Serial.printf("Connected: %d\n", conn_id);
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3ble_authenticated Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72!Tff7b72= Te6edf3BT_STATE_PAIRINGTb4b4b4) Tb4b4b4{ Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4; Tb4b4b4}
Te6edf3cable_state Tff7b72= Te6edf3CABLE_STATE_DISCONNECTEDTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_disconnect_callbackTb4b4b4(Te6edf3BLEServer Tff7b72*Te6edf3serverTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3conn_id Tff7b72= Te6edf3serverTff7b72-Tff7b72>Te6edf3getConnIdTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Serial.printf("Disconnected: %d\n", conn_id);
Te6edf3display_unblankTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3ble_authenticated Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffbt_setup_hwTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT setup hw");
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3bt_readyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_CONF_BTTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3BT_ENABLE_BYTETb4b4b4) Tb4b4b4{
Te6edf3bt_enabled Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3bt_enabled Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3btStartTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3esp_bluedroid_initTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ESP_OKTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3esp_bluedroid_enableTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ESP_OKTb4b4b4) Tb4b4b4{
Tff7b72const Tffa657uint8_tTff7b72* Te6edf3bda_ptr Tff7b72= Te6edf3esp_bt_dev_get_addressTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657char Tff7b72*Te6edf3data Tff7b72= Tb4b4b4(Tffa657charTff7b72*Tb4b4b4)Te6edf3mallocTb4b4b4(Te6edf3BT_DEV_ADDR_LENTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3BT_DEV_ADDR_LENTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3bda_ptrTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tb4b4b4}
Te6edf3dataTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4] Tff7b72= Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_SIGNATURETb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657unsigned Tffa657char Tff7b72*Te6edf3hash Tff7b72= Te6edf3MD5Tff7b72:Tff7b72:Te6edf3make_hashTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3BT_DEV_ADDR_LENTb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3bt_dhTb4b4b4, Te6edf3hashTb4b4b4, Te6edf3BT_DEV_HASH_LENTb4b4b4)Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3bt_devnameTb4b4b4, Ta5d6ff"Ta5d6ffRNode %02X%02XTa5d6ff"Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff14Tb4b4b4]Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff15Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3freeTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4;

Te6edf3bt_security_setupTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3bt_ready Tff7b72= Tffa657trueTb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;

Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_security_setupTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Executing BT security setup");
Tff7b72if Tb4b4b4(Te6edf3pairing_pin Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ Te6edf3bt_update_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}
Tffa657uint32_t Te6edf3passkey Tff7b72= Te6edf3pairing_pinTb4b4b4;
T8b949e// Serial.printf("Passkey is %d\n", passkey);

Tffa657uint8_t Te6edf3key_size Tff7b72= T79c0ff16Tb4b4b4;
Tffa657uint8_t Te6edf3init_key Tff7b72= Te6edf3ESP_BLE_ENC_KEY_MASK Tff7b72| Te6edf3ESP_BLE_ID_KEY_MASKTb4b4b4;
Tffa657uint8_t Te6edf3rsp_key Tff7b72= Te6edf3ESP_BLE_ENC_KEY_MASK Tff7b72| Te6edf3ESP_BLE_ID_KEY_MASKTb4b4b4;

Te6edf3esp_ble_auth_req_t Te6edf3auth_req Tff7b72= Te6edf3ESP_LE_AUTH_REQ_SC_MITM_BONDTb4b4b4;
Tffa657uint8_t Te6edf3auth_option Tff7b72= Te6edf3ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLETb4b4b4;
Tffa657uint8_t Te6edf3oob_support Tff7b72= Te6edf3ESP_BLE_OOB_DISABLETb4b4b4;

Te6edf3esp_ble_io_cap_t Te6edf3iocap Tff7b72= Te6edf3ESP_IO_CAP_OUTTb4b4b4;

Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_SET_STATIC_PASSKEYTb4b4b4, Tff7b72&Te6edf3passkeyTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint32_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_AUTHEN_REQ_MODETb4b4b4, Tff7b72&Te6edf3auth_reqTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_IOCAP_MODETb4b4b4, Tff7b72&Te6edf3iocapTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_MAX_KEY_SIZETb4b4b4, Tff7b72&Te6edf3key_sizeTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTHTb4b4b4, Tff7b72&Te6edf3auth_optionTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_OOB_SUPPORTTb4b4b4, Tff7b72&Te6edf3oob_supportTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_SET_INIT_KEYTb4b4b4, Tff7b72&Te6edf3init_keyTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3esp_ble_gap_set_security_paramTb4b4b4(Te6edf3ESP_BLE_SM_SET_RSP_KEYTb4b4b4, Tff7b72&Te6edf3rsp_keyTb4b4b4, Tff7b72sizeofTb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffupdate_btTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairing Tff7b72&Tff7b72& Te6edf3millisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3bt_pairing_started Tff7b72>Tff7b72= Te6edf3BT_PAIRING_TIMEOUTTb4b4b4) Tb4b4b4{
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_CONNECTED Tff7b72&Tff7b72& Te6edf3millisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3SerialBTTb4b4b4.Te6edf3lastFlushTime Tff7b72>Tff7b72= Te6edf3BLE_FLUSH_TIMEOUTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3SerialBTTb4b4b4.Te6edf3transmitBufferLength Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3bt_flushTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif

Tff7b72#Tff7b72elif MCU_VARIANT == MCU_NRF52
Tffa657uint32_t Te6edf3pairing_pin Tff7b72= T79c0ff0Tb4b4b4;

Tffa657uint8_t Td2a8ffeeprom_readTb4b4b4(Tffa657uint32_t Te6edf3mapped_addrTb4b4b4)Tb4b4b4;

Tffa657void Td2a8ffbt_stopTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT Stop");
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72!Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_disable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT Disable pairing");
Te6edf3bt_allow_pairing Tff7b72= Tffa657falseTb4b4b4;
Te6edf3pairing_pin Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_flushTb4b4b4(Tb4b4b4) Tb4b4b4{ Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4) Tb4b4b4{ Te6edf3SerialBTTb4b4b4.Te6edf3flushTXDTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4} Tb4b4b4}

Tffa657void Td2a8ffbt_pairing_completeTb4b4b4(Tffa657uint16_t Te6edf3conn_handleTb4b4b4, Tffa657uint8_t Te6edf3auth_statusTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT pairing complete");
Te6edf3BLEConnectionTff7b72* Te6edf3connection Tff7b72= Te6edf3BluefruitTb4b4b4.Te6edf3ConnectionTb4b4b4(Te6edf3conn_handleTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3auth_status Tff7b72=Tff7b72= Te6edf3BLE_GAP_SEC_STATUS_SUCCESSTb4b4b4) Tb4b4b4{
Te6edf3ble_gap_conn_sec_mode_t Te6edf3security Tff7b72= Te6edf3connectionTff7b72-Tff7b72>Te6edf3getSecureModeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Serial.println("Bonding success");

T8b949e// On the NRF52 it is not possible with the Arduino library to reject
T8b949e// requests from devices with no IO capabilities, which would allow
T8b949e// bypassing pin entry through pairing using the "just works" mode.
T8b949e// Therefore, we must check the security level of the connection after
T8b949e// pairing to ensure "just works" has not been used. If it has, we need
T8b949e// to disconnect, unpair and delete any bonding information immediately.
T8b949e// Settings on the SerialBT service should prevent unauthorised access to
T8b949e// the serial port anyway, but this is still wise to do regardless.
T8b949e//
T8b949e// Note: It may be nice to have this done in the BLESecurity class in the
T8b949e// future, but as it stands right now I'd have to fork the BSP to do
T8b949e// that, which I don't fancy doing. Impact on security is likely minimal.
T8b949e// Requires investigation.

Tff7b72if Tb4b4b4(Te6edf3securityTb4b4b4.Te6edf3sm Tff7b72=Tff7b72= T79c0ff1 Tff7b72&Tff7b72& Te6edf3securityTb4b4b4.Te6edf3lv Tff7b72>Tff7b72= T79c0ff3Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Auth level success");
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4;
Te6edf3cable_state Tff7b72= Te6edf3CABLE_STATE_DISCONNECTEDTb4b4b4;
Te6edf3connectionTff7b72-Tff7b72>Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Serial.println("Auth level failure, debonding");
Tff7b72if Tb4b4b4(Te6edf3connectionTff7b72-Tff7b72>Te6edf3bondedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3connectionTff7b72-Tff7b72>Te6edf3removeBondKeyTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}
Te6edf3connectionTff7b72-Tff7b72>Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Serial.println("Bonding failure");
Te6edf3connectionTff7b72-Tff7b72>Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Td2a8ffbt_passkey_callbackTb4b4b4(Tffa657uint16_t Te6edf3conn_handleTb4b4b4, Tffa657uint8_t Tff7b72const Te6edf3passkeyTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4, Tffa657bool Te6edf3match_requestTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Passkey callback");
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairingTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_connect_callbackTb4b4b4(Tffa657uint16_t Te6edf3conn_handleTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Connect callback");
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_CONNECTEDTb4b4b4;
Te6edf3cable_state Tff7b72= Te6edf3CABLE_STATE_DISCONNECTEDTb4b4b4;

Te6edf3BLEConnectionTff7b72* Te6edf3conn Tff7b72= Te6edf3BluefruitTb4b4b4.Te6edf3ConnectionTb4b4b4(Te6edf3conn_handleTb4b4b4)Tb4b4b4;
Te6edf3connTff7b72-Tff7b72>Te6edf3requestPHYTb4b4b4(Te6edf3BLE_GAP_PHY_2MBPSTb4b4b4)Tb4b4b4;
Te6edf3connTff7b72-Tff7b72>Te6edf3requestMtuExchangeTb4b4b4(T79c0ff512Tff7b72+T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3connTff7b72-Tff7b72>Te6edf3requestDataLengthUpdateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Td2a8ffbt_disconnect_callbackTb4b4b4(Tffa657uint16_t Te6edf3conn_handleTb4b4b4, Tffa657uint8_t Te6edf3reasonTb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Disconnect callback");
Tff7b72if Tb4b4b4(Te6edf3reason Tff7b72!Tff7b72= Te6edf3BLE_GAP_SEC_STATUS_SUCCESSTb4b4b4) Tb4b4b4{
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Td2a8ffbt_update_passkeyTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Update passkey");
Te6edf3pairing_pin Tff7b72= Te6edf3randomTb4b4b4(T79c0ff899999Tb4b4b4)Tff7b72+T79c0ff100000Tb4b4b4;
Te6edf3bt_ssp_pin Tff7b72= Te6edf3pairing_pinTb4b4b4;
Tb4b4b4}

Tffa657uint32_t Td2a8ffbt_get_passkeyTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("API passkey request");
Tff7b72if Tb4b4b4(Te6edf3pairing_pin Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ Te6edf3bt_update_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}
Tff7b72return Te6edf3pairing_pinTb4b4b4;
Tb4b4b4}

Tffa657bool Td2a8ffbt_setup_hwTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("Setup HW");
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3bt_readyTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if HAS_EEPROM
Tff7b72if Tb4b4b4(Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_CONF_BTTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3BT_ENABLE_BYTETb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72else
Tff7b72if Tb4b4b4(Te6edf3eeprom_readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_CONF_BTTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3BT_ENABLE_BYTETb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3bt_enabled Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3bt_enabled Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3BluefruitTb4b4b4.Te6edf3configPrphBandwidthTb4b4b4(Te6edf3BANDWIDTH_MAXTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3autoConnLedTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3BluefruitTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3pin Tff7b72= Te6edf3bt_get_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657char Te6edf3pin_charTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3pin_charTb4b4b4,Ta5d6ff"Ta5d6ff%luTa5d6ff"Tb4b4b4, Te6edf3pinTb4b4b4)Tb4b4b4;

Te6edf3BluefruitTb4b4b4.Te6edf3setTxPowerTb4b4b4(T79c0ff8Tb4b4b4)Tb4b4b4; T8b949e// Check bluefruit.h for supported values
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setIOCapsTb4b4b4(Tffa657trueTb4b4b4, Tffa657falseTb4b4b4, Tffa657falseTb4b4b4)Tb4b4b4; T8b949e// display, yes; yes / no, no; keyboard, no
T8b949e// This device is indeed capable of yes / no through the pairing mode
T8b949e// being set, but I have chosen to set it thus to force the input of the
T8b949e// pin on the device initiating the pairing.

Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setMITMTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setPairPasskeyCallbackTb4b4b4(Te6edf3bt_passkey_callbackTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setSecuredCallbackTb4b4b4(Te6edf3bt_connect_callbackTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setPINTb4b4b4(Te6edf3pin_charTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3PeriphTb4b4b4.Te6edf3setDisconnectCallbackTb4b4b4(Te6edf3bt_disconnect_callbackTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setPairCompleteCallbackTb4b4b4(Te6edf3bt_pairing_completeTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3PeriphTb4b4b4.Te6edf3setConnIntervalTb4b4b4(T79c0ff6Tb4b4b4, T79c0ff12Tb4b4b4)Tb4b4b4; T8b949e// 7.5 - 15 ms

Tff7b72const Te6edf3ble_gap_addr_t Te6edf3gap_addr Tff7b72= Te6edf3BluefruitTb4b4b4.Te6edf3getAddrTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657char Tff7b72*Te6edf3data Tff7b72= Tb4b4b4(Tffa657charTff7b72*Tb4b4b4)Te6edf3mallocTb4b4b4(Te6edf3BT_DEV_ADDR_LENTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3BT_DEV_ADDR_LENTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3gap_addrTb4b4b4.Te6edf3addrTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if HAS_EEPROM
Te6edf3dataTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4] Tff7b72= Te6edf3EEPROMTb4b4b4.Te6edf3readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_SIGNATURETb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3dataTb4b4b4[Te6edf3BT_DEV_ADDR_LENTb4b4b4] Tff7b72= Te6edf3eeprom_readTb4b4b4(Te6edf3eeprom_addrTb4b4b4(Te6edf3ADDR_SIGNATURETb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tffa657unsigned Tffa657char Tff7b72*Te6edf3hash Tff7b72= Te6edf3MD5Tff7b72:Tff7b72:Te6edf3make_hashTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3BT_DEV_ADDR_LENTb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3bt_dhTb4b4b4, Te6edf3hashTb4b4b4, Te6edf3BT_DEV_HASH_LENTb4b4b4)Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3bt_devnameTb4b4b4, Ta5d6ff"Ta5d6ffRNode %02X%02XTa5d6ff"Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff14Tb4b4b4]Tb4b4b4, Te6edf3bt_dhTb4b4b4[T79c0ff15Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3freeTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4;

Te6edf3bt_ready Tff7b72= Tffa657trueTb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;

Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{ Tff7b72return Tffa657falseTb4b4b4; Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3bt_startTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT Start");
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Tb4b4b4{
Te6edf3BluefruitTb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3bt_devnameTb4b4b4)Tb4b4b4;
Te6edf3bledisTb4b4b4.Te6edf3setManufacturerTb4b4b4(Te6edf3BLE_MANUFACTURERTb4b4b4)Tb4b4b4;
Te6edf3bledisTb4b4b4.Te6edf3setModelTb4b4b4(Te6edf3BLE_MODELTb4b4b4)Tb4b4b4;
T8b949e// start device information service
Te6edf3bledisTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3blebasTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;

T8b949e// Guard to ensure SerialBT service is not duplicated through BT being power cycled
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3SerialBT_initTb4b4b4) Tb4b4b4{
Te6edf3SerialBTTb4b4b4.Te6edf3bufferTXDTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4; T8b949e// enable buffering

Te6edf3SerialBTTb4b4b4.Te6edf3setPermissionTb4b4b4(Te6edf3SECMODE_ENC_WITH_MITMTb4b4b4, Te6edf3SECMODE_ENC_WITH_MITMTb4b4b4)Tb4b4b4; T8b949e// enable encryption for BLE serial
Te6edf3SerialBTTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialBT_init Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}

Te6edf3BluefruitTb4b4b4.Te6edf3AdvertisingTb4b4b4.Te6edf3addFlagsTb4b4b4(Te6edf3BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODETb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3AdvertisingTb4b4b4.Te6edf3addTxPowerTb4b4b4(Tb4b4b4)Tb4b4b4;

T8b949e// Include bleuart 128-bit uuid
Te6edf3BluefruitTb4b4b4.Te6edf3AdvertisingTb4b4b4.Te6edf3addServiceTb4b4b4(Te6edf3SerialBTTb4b4b4)Tb4b4b4;

T8b949e// There is no room for Name in Advertising packet
T8b949e// Use Scan response for Name
Te6edf3BluefruitTb4b4b4.Te6edf3ScanResponseTb4b4b4.Te6edf3addNameTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3BluefruitTb4b4b4.Te6edf3AdvertisingTb4b4b4.Te6edf3startTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;

Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_ONTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657bool Te6edf3bt_initTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT init");
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bt_setup_hwTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_enabled Tff7b72&Tff7b72& Tff7b72!Te6edf3console_activeTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}

Tffa657void Te6edf3bt_enable_pairingTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Serial.println("BT enable pairing");
Tff7b72if Tb4b4b4(Te6edf3bt_state Tff7b72=Tff7b72= Te6edf3BT_STATE_OFFTb4b4b4) Te6edf3bt_startTb4b4b4(Tb4b4b4)Tb4b4b4;

Tffa657uint32_t Te6edf3pin Tff7b72= Te6edf3bt_get_passkeyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657char Te6edf3pin_charTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3pin_charTb4b4b4,Ta5d6ff"Ta5d6ff%luTa5d6ff"Tb4b4b4, Te6edf3pinTb4b4b4)Tb4b4b4;
Te6edf3BluefruitTb4b4b4.Te6edf3SecurityTb4b4b4.Te6edf3setPINTb4b4b4(Te6edf3pin_charTb4b4b4)Tb4b4b4;

Te6edf3bt_allow_pairing Tff7b72= Tffa657trueTb4b4b4;
Te6edf3bt_pairing_started Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3bt_state Tff7b72= Te6edf3BT_STATE_PAIRINGTb4b4b4;
Te6edf3kiss_indicate_btpinTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Tffa657void Te6edf3bt_debond_allTb4b4b4(Tb4b4b4) Tb4b4b4{ Tb4b4b4}

Tffa657void Te6edf3update_btTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3bt_allow_pairing Tff7b72&Tff7b72& Te6edf3millisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3bt_pairing_started Tff7b72>Tff7b72= Te6edf3BT_PAIRING_TIMEOUTTb4b4b4) Tb4b4b4{
Te6edf3bt_disable_pairingTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────